package com.cloudy.ec2.request;

import static com.cloudy.impl.Constants.DATE_FORMAT;
import static com.cloudy.impl.Constants.DOC_VERSION;
import static com.cloudy.impl.Constants.GET;
import static com.cloudy.impl.Constants.SIGNATURE_METHOD;
import static com.cloudy.impl.Constants.SIGNATURE_VERSION;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import com.cloudy.exception.AWSAccessException;
import com.cloudy.impl.AWSRequest;
import com.cloudy.impl.EC2ServiceCaller;
import com.cloudy.impl.SuccessHandler;
import com.cloudy.impl.SuccessHandlerWithResponse;
import com.cloudy.security.AWSRequestSigner;
import com.cloudy.security.AccessIdentifiers;
import com.cloudy.security.EC2RequestSigner;
import com.cloudy.utility.CloudyUtility;

public abstract class EC2Request implements AWSRequest{
	private static final int FIVE_MINUTES = 5*60*1000;
	public static AWSRequestSigner rs = new EC2RequestSigner();
	public static EC2ServiceCaller sc = new EC2ServiceCaller();
	
	public EC2Request() {
		attributes.put("Action", this.getClass().getSimpleName());
		attributes.put("Version", DOC_VERSION);
		attributes.put("SignatureVersion", SIGNATURE_VERSION);
		attributes.put("SignatureMethod", SIGNATURE_METHOD);
		attributes.put("AWSAccessKeyId", AccessIdentifiers.getAccessKeyID());
		attributes.put("Expires", new SimpleDateFormat(DATE_FORMAT).format(new Date(GregorianCalendar.getInstance().getTimeInMillis()+FIVE_MINUTES)));	
	}
	
	private Map<String, String> attributes = new HashMap<String, String>();
	public String getQueryString(){
		return CloudyUtility.getQueryString(attributes);
	}	
	public Map<String, String> getAttributes(){
		return attributes;
	}
	
	public void putSignature(String value){
		attributes.put("Signature", value);
	}
	protected void putAttribute(String key, String value){
		attributes.put(key, value);
	}
	private void addParameters(String key, String value) {
		attributes.put(key, value);
	}

	public <T> T execute() throws AWSAccessException {
		rs.sign(this);
        Object result = sc.callService(this);
		return (T)result;
	}
	
	protected void addAttributes(String attributeName, String[] source) {
		int counter = 1;
		if(source==null)
			return;
		
		for (int i = 0; i < source.length; i++) {
			if (source[i]!=null){
				addParameters(attributeName+"."+counter, source[i]);
				counter++;
			}
		}
	}

	public String getRequestMethod() {
		// TODO Auto-generated method stub
		return GET;
	}

	public SuccessHandler getSuccessHandler(){
		return new SuccessHandlerWithResponse();
	}
}
